using NodeCanvas.BehaviourTrees;
using UnityEngine;

namespace NodeCanvas.StateMachines
{
	[AddComponentMenu("")]
	[Name("BehaviourTree")]
	[Category("Nested")]
	[Description("Execute a Behaviour Tree OnEnter. OnExit that Behavior Tree will be stoped. You can optionaly specify a Success Event and a Failure Event which will be sent when the BT's root node status returns either of the two. If so, use alongside with a CheckEvent on Transition.")]
	public class FSMNestedBTState : FSMState, INestedNode
	{
		private enum ExecutionMode
		{
			RunOnce = 0,
			RunForever = 1
		}

		[SerializeField]
		private ExecutionMode executionMode = ExecutionMode.RunForever;

		[SerializeField]
		private float updateInterval;

		[SerializeField]
		private BehaviourTree _nestedBT;

		[SerializeField]
		private string successEvent;

		[SerializeField]
		private string failureEvent;

		private bool instantiated;

		private bool BTIsFinished;

		private BehaviourTree nestedBT
		{
			get
			{
				return _nestedBT;
			}
			set
			{
				_nestedBT = value;
			}
		}

		[HideInInspector]
		public Graph nestedGraph
		{
			get
			{
				return nestedBT;
			}
			set
			{
				nestedBT = (BehaviourTree)value;
			}
		}

		protected override void Init()
		{
			CheckInstance();
		}

		protected override void Enter()
		{
			if (!nestedBT)
			{
				Finish(false);
				return;
			}
			CheckInstance();
			BTIsFinished = false;
			nestedBT.runForever = executionMode == ExecutionMode.RunForever;
			nestedBT.updateInterval = updateInterval;
			nestedBT.StartGraph(base.graphAgent, base.graphBlackboard, delegate
			{
				BTIsFinished = true;
			});
		}

		protected override void Stay()
		{
			if (!string.IsNullOrEmpty(successEvent) && nestedBT.rootStatus == Status.Success)
			{
				SendEvent(successEvent);
			}
			if (!string.IsNullOrEmpty(failureEvent) && nestedBT.rootStatus == Status.Failure)
			{
				SendEvent(failureEvent);
			}
			if (BTIsFinished)
			{
				Finish();
			}
		}

		protected override void Exit()
		{
			if ((bool)nestedBT && nestedBT.isRunning)
			{
				nestedBT.StopGraph();
			}
		}

		protected override void Pause()
		{
			if ((bool)nestedBT)
			{
				nestedBT.PauseGraph();
			}
		}

		private void CheckInstance()
		{
			if (!instantiated && nestedBT != null && nestedBT.transform.parent != base.graph.transform)
			{
				nestedBT = Object.Instantiate(nestedBT, base.transform.position, base.transform.rotation);
				nestedBT.transform.parent = base.graph.transform;
				instantiated = true;
			}
		}
	}
}
